package ks.client.game;

import ks.client.interfaces.IGameInterface;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

/**
 * Primary Window for managing the Container within which the solitaire
 * action takes place.<p>
 *
 * GameWindow can speak back to the primary connection through 
 * its helperClient (which it shares with KombatClient).<p>
 * <p>
 * Intended to be glorified arbiter among all game variation types.
 * 
 * @author George T. Heineman (heineman@cs.wpi.edu)
 */
public class GameFrame extends JFrame {
	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 3544957666427353398L;

	/** Knows which table is being played. */
	int tableNumber;

	/** Knows callback. */
	IGameInterface callback;
	
	/** Initial width for the window. Must never shrink less than this. */
	protected int initialWidth = 769;

	/** Initial height for the window. Must never shrink less than this. */
	protected int initialHeight = 635;

	/** Last height for the window. Start with initial height. */
	protected int lastHeight = 635;

	/** Last width for the window. Start with initial width. */
	protected int lastWidth = 769;

	/** output and input. */
	JTextArea output;
	JTextField input;
	
	/** Game contents (works for both AWT and Swing objects). */
	java.awt.Component gamePanel = null;
	
	/** Controls (works for both AWT and Swing objects). */
	java.awt.Component gameControls = null;
	
	/** game-specific info. */
	GameInformation info;
	
	public GameFrame(GameInformation info) {
		super(info.game);
		
		this.info = info;
		initialize();
	}

	/** Set the table number. */
	public void setTableNumber (int tn) {
		tableNumber = tn;
	}
	
	/** Return the table number. */
	public int getTableNumber() {
		return tableNumber;
	}
	
	/** Set the callback. */
	public void setGameInterface(IGameInterface igi) {
		this.callback = igi;
	}
	
	/** Allow external access to the game information. */
	public GameInformation getGameInformation() {
		return info;
	}
	
	/**
	 * Initialize the class.
	 */
	private void initialize() {
		setName("GameWindow");
		setPreferredSize(new Dimension(800, 635));
		setSize (800, 635);
		setTitle("Sample Game");
		
		JPanel panel = new JPanel();
		GroupLayout layout = new GroupLayout(panel);
		panel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);
		
		// solitaire game (heavy weight container. Hope not an issue).
		gamePanel = info.getGameContainer();
		gameControls = info.getGameControls();		
		
		output = new JTextArea(6, 30);
		output.setEditable(false);
		output.setMaximumSize(new Dimension (280, 120));
		input = new JTextField(30);
		input.setMaximumSize(new Dimension (280, 20));
		
		input.addActionListener (new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String s = input.getText();
				input.setText("");
				callback.sendTableChat(tableNumber, s);
				
				// append locally
				output.append(s + "\n");
			}
		});
		
		layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addComponent(gamePanel)
				.addGroup(layout.createSequentialGroup()
						.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
								.addComponent(output)
								.addComponent(input))
						.addComponent(gameControls))
						);
		
		layout.setVerticalGroup(layout.createSequentialGroup()
				.addComponent(gamePanel)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addGroup(layout.createSequentialGroup()
								.addComponent(output)
								.addComponent(input))
						.addComponent(gameControls))
						);
						
		// deal with window closing
		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

		this.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				int selection = JOptionPane.showConfirmDialog(null,
						"Are you sure you want exit game and underlying table?", "Kombat Games",
						JOptionPane.YES_NO_OPTION,
						JOptionPane.WARNING_MESSAGE);
				if (selection == JOptionPane.YES_OPTION) {
					callback.leaveGame(tableNumber);
					
					// Heineman: have to be clean about the shutdown wrt game manager.
					//closeDown();
					GameManager.instance().exitGameWindow();
				} else {
					
				}
			}
		});
		
		add(panel);
	}
	

	/** 
	 * Close down the game frame.
	 */
	public void closeDown() {
		// shutdown here.
		info.stop();
		
		setVisible(false);
		dispose();
	}

	/**
	 * Table chat messages are handled here.
	 * 
	 * @param fromPlayerID   player issuing the chat
	 * @param text           actual chat
	 */
	public void showTableText(String fromPlayerID, String text) {
		output.append(fromPlayerID + ": " + text + "\n");
	}

	/**
	 * Make it possible to extract table chat history
	 */
	public String getTableTextContents() {
		return output.getText();
	}

	/**
	 * Make it possible to reset table chat history when changing games on the same table.
	 *  
	 * @param oldChat
	 */
	public void setTableTextContents(String oldChat) {
		output.setText(oldChat);
	}
	
}
